import 'dart:async';

import 'package:flutter/material.dart';
import 'package:flutter_class2/3681/news/news_json_resp.dart';
import 'package:sqflite/sqflite.dart';
import 'package:path/path.dart';
import 'package:shared_preferences/shared_preferences.dart';

// 0 SQLite账户数据
class Account {

  String _id;//用户名
  String _password;//密码
  String _phoneNum;//手机号
  String _email;//邮箱
  String _nickName;//昵称
  String _headPic;//头像
  int _sex;//性别
  int _age;//年龄
  int _level;//等级
  String _resetPWQuestion;//密码找回问题
  String _resetPWAnswer;//密码找回答案

  Account(this._id , this._password, this._phoneNum, this._email, this._nickName, this._headPic, this._sex, this._age, this._level, this._resetPWQuestion, this._resetPWAnswer);

  Account.map(dynamic obj) {
    this._id = obj['id'];
    this._password = obj['password'];
    this._phoneNum = obj['phoneNum'];
    this._email = obj['email'];
    this._nickName = obj['nickName'];
    this._headPic = obj['headPic'];
    this._sex = obj['sex'];
    this._age = obj['age'];
    this._level = obj['level'];
    this._resetPWQuestion = obj['resetPWQuestion'];
    this._resetPWAnswer = obj['resetPWAnswer'];
  }

  String get id => _id;
  String get password => _password;
  String get phoneNum => _phoneNum;
  String get email => _email;
  String get nickName => _nickName;
  String get headPic => _headPic;
  int get sex => _sex;
  int get age => _age;
  int get level => _level;
  String get resetPWQuestion => _resetPWQuestion;
  String get resetPWAnswer => _resetPWAnswer;

  Map<String, dynamic> toMap() {
    var map = new Map<String, dynamic>();
    if (_id != null) {
      map['id'] = _id;
    }
    // map['id'] = _id;
    map['password'] = _password ;
    map['phoneNum'] = _phoneNum ;
    map['email'] = _email ;
    map['nickName'] = _nickName ;
    map['headPic'] = _headPic ;
    map['sex'] = _sex ;
    map['age'] = _age ;
    map['level'] = _level ;
    map['resetPWQuestion'] = _resetPWQuestion ;
    map['resetPWAnswer'] = _resetPWAnswer ;
    return map;
  }

  Account.fromMap(Map<String, dynamic> map) {
    this._id = map['id'].toString();
    this._password = map['password'];
    this._phoneNum = map['phoneNum'];
    this._email = map['email'];
    this._nickName = map['nickName'];
    this._headPic = map['headPic'];
    this._sex = int.parse(map['sex']);
    this._age = int.parse(map['age']);
    this._level = int.parse(map['level']);
    this._resetPWQuestion = map['resetPWQuestion'];
    this._resetPWAnswer = map['resetPWAnswer'];
  }
}

// 0 SQLite对账户进行操作的工具类
class AccountDatabaseHelper {
  static final AccountDatabaseHelper _instance = new AccountDatabaseHelper.internal();

  factory AccountDatabaseHelper() => _instance;

  final String tableName = 'mengTable';
  final String columnId = 'id';//登录名
  final String password = 'password';//密码
  final String phoneNum = 'phoneNum';//手机号
  final String email = 'email';//邮箱
  final String nickName= 'nickName';//昵称
  final String headPic= 'headPic';//头像
  final String sex = 'sex';//性别
  final String age = 'age';//年龄
  final String level = 'level';//等级
  final String resetPWQuestion = 'resetPWQuestion';//密码找回问题
  final String resetPWAnswer = 'resetPWAnswer';//密码找回答案

  static Database _db;

  AccountDatabaseHelper.internal();

  Future<Database> get db async {
    if (_db != null) {
      return _db;
    }
    _db = await initDb();

    return _db;
  }

  initDb() async {
    String databasesPath = await getDatabasesPath();
    String path = join(databasesPath, 'mengAccount.db');

//    await deleteDatabase(path); // just for testing

    var db = await openDatabase(path, version: 1, onCreate: _onCreate);
    return db;
  }

  void _onCreate(Database db, int newVersion) async {
    await db.execute(
        'CREATE TABLE $tableName($columnId INTEGER PRIMARY KEY AUTOINCREMENT,'
            ' $password TEXT, $phoneNum TEXT, $email TEXT, $nickName TEXT,'
            ' $headPic TEXT, $sex TEXT, $age TEXT, $level TEXT,'
            ' $resetPWQuestion TEXT, $resetPWAnswer TEXT)');
  }

  //增加一条数据
  Future<int> saveAccount(Account account) async {
    var dbClient = await db;
    var result = await dbClient.insert(tableName, account.toMap());
//    var result = await dbClient.rawInsert(
//        'INSERT INTO $tableNote ($columnTitle, $columnDescription) VALUES (\'${note.title}\', \'${note.description}\')');
    return result;
  }

  //获取所有数据
  Future<List> getAllAccounts() async {
    var dbClient = await db;
    var result = await dbClient.query(
        tableName,
        columns: [columnId, password, phoneNum , email , nickName , headPic , sex , age , level , resetPWQuestion , resetPWAnswer]);
//    var result = await dbClient.rawQuery('SELECT * FROM $tableNote');
    return result.toList();
  }

  //获取数据库中的数据数量
  Future<int> getCount() async {
    var dbClient = await db;
    return Sqflite.firstIntValue(await dbClient.rawQuery('SELECT COUNT(*) FROM $tableName'));
  }

  //根据id获取指定的数据
  Future<Account> getAccount(String id) async {
    var dbClient = await db;
    List<Map> result = await dbClient.query(tableName,
        columns: [columnId, password, phoneNum , email , nickName , headPic , sex , age , level , resetPWQuestion , resetPWAnswer],
        where: '$columnId = ?',
        whereArgs: [id]);
    // var result = await dbClient.rawQuery('SELECT * FROM $tableName WHERE $columnId = $id');

    if (result.length > 0) {
      Account account = Account.fromMap(result.first);
      return account;
    }else{
      return null;
    }
  }

  //删除数据
  Future<int> deleteAccount(String id) async {
    var dbClient = await db;
    return await dbClient.delete(tableName, where: '$columnId = ?', whereArgs: [id]);
//    return await dbClient.rawDelete('DELETE FROM $tableNote WHERE $columnId = $id');
  }

  //修改一条数据
  Future<int> updateAccount(Account account) async {
    var dbClient = await db;
    return await dbClient.update(tableName, account.toMap(), where: "$columnId = ?", whereArgs: [account.id]);
//    return await dbClient.rawUpdate(
//        'UPDATE $tableNote SET $columnTitle = \'${note.title}\', $columnDescription = \'${note.description}\' WHERE $columnId = ${note.id}');
  }

  //关闭数据库
  Future close() async {
    var dbClient = await db;
    return dbClient.close();
  }
}

// 1 登陆时记住密码的相关类（仅用户名和密码）
class AccountLite{
  String _id;
  String _password;

  AccountLite(this._id,
      this._password);

  get id => _id;
  get password => _password;

  @override
  String toString() {
    return "|$_id $_password|";
  }

  @override
  bool operator ==(other) {
    return (_id == other._id) && (_password == other._password);
  }
}

// 1 登陆时记住密码的相关工具
class SharedPreferenceUtil {
  static const String ACCOUNT_NUMBER = "account_number";
  static const String ID = "id";
  static const String PASSWORD = "password";

  ///删掉单个账号的记录
  static void delAccountLite(AccountLite accountLite) async {
    SharedPreferences sp = await SharedPreferences.getInstance();
    List<AccountLite> list = await getAccountLites();
    list.remove(accountLite);
    saveAccountLites(list, sp);
  }

  ///保存账号，如果重复，就将最近登录账号放在第一个
  static void saveAccountLite(AccountLite accountLite) async {
    SharedPreferences sp = await SharedPreferences.getInstance();
    List<AccountLite> list = await getAccountLites();
    addNoRepeat(list, accountLite);
    saveAccountLites(list, sp);
  }

  ///去重并维持次序
  static void addNoRepeat(List<AccountLite> accountLites, AccountLite accountLite ) {
    if (accountLites.contains(accountLite)) {
      accountLites.remove(accountLite);
    }
    accountLites.insert(0, accountLite);
  }

  ///获取已经登录的账号列表
  static Future<List<AccountLite>> getAccountLites() async {
    List<AccountLite> list = new List();
    SharedPreferences sp = await SharedPreferences.getInstance();
    int num = sp.getInt(ACCOUNT_NUMBER) ?? 0;
    for (int i = 0; i < num; i++) {
      String id = sp.getString("$ID$i");
      String password = sp.getString("$PASSWORD$i");
      list.add(AccountLite(id, password));
    }
    return list;
  }

  ///保存账号列表
  static saveAccountLites(List<AccountLite> accountLites, SharedPreferences sp){
    sp.clear();
    int size = accountLites.length;
    for (int i = 0; i < size; i++) {
      sp.setString("$ID$i", accountLites[i].id);
      sp.setString("$PASSWORD$i", accountLites[i].password);
    }
    sp.setInt(ACCOUNT_NUMBER, size);
  }
}

// 2 SQLite对新闻数据进行（缓存）操作的工具类
class DataItemDatabaseHelper {
  static final DataItemDatabaseHelper _instance = new DataItemDatabaseHelper.internal();
  factory DataItemDatabaseHelper() => _instance;

  final String tableName = 'mengDataItemTable';
  final String newsId = 'newsId'; // id
  final String uniquekey = 'uniquekey'; // 访问接口的唯一key
  final String title = 'title'; // 新闻标题
  final String date = 'date'; // 新闻时间
  final String category = 'category';
  final String author_name = 'author_name'; // 新闻作者
  final String url = 'url'; // 新闻的url（进入详情页）
  final String thumbnail_pic_s = 'thumbnail_pic_s'; // 新闻封面图
  final String thumbnail_pic_s02 = 'thumbnail_pic_s02';
  final String thumbnail_pic_s03 = 'thumbnail_pic_s03';

  // DataItemDatabaseHelper._privateConstructor();
  // static final DataItemDatabaseHelper _instance = DataItemDatabaseHelper._privateConstructor();
  static Database _db;

  DataItemDatabaseHelper.internal();

  Future<Database> get db async {
    if (_db != null) {
      return _db;
    }
    _db = await initDb();

    return _db;
  }

  initDb() async {
    String databasesPath = await getDatabasesPath();
    String path = join(databasesPath, 'mengDataItemTable.db');

//    await deleteDatabase(path); // just for testing

    var db = await openDatabase(path, version: 1, onCreate: _onCreate);
    return db;
  }

  void _onCreate(Database db, int newVersion) async {
    await db.execute(
        'CREATE TABLE $tableName($newsId INTEGER PRIMARY KEY AUTOINCREMENT,'
            ' $uniquekey TEXT, $title TEXT, $date TEXT, $category TEXT,'
            ' $author_name TEXT, $url TEXT, $thumbnail_pic_s TEXT, $thumbnail_pic_s02 TEXT,'
            ' $thumbnail_pic_s03 TEXT)');
  }

  //增加一条数据
  Future<int> saveDataItem(String newsId, DataItem dataItem) async {
    var dbClient = await db;
    var result = await dbClient.insert(tableName, dataItem.toMap());
    return result;
  }

  //获取所有数据
  Future<List> getAllDataItems() async {
    var dbClient = await db;
    var result = await dbClient.query(
        tableName,
        columns: [newsId, uniquekey, title, date , category , author_name , url , thumbnail_pic_s , thumbnail_pic_s02 , thumbnail_pic_s03 ,]);
//    var result = await dbClient.rawQuery('SELECT * FROM $tableNote');
    return result.toList();
  }

  //获取数据库中的数据数量
  Future<int> getCount() async {
    var dbClient = await db;
    return Sqflite.firstIntValue(await dbClient.rawQuery('SELECT COUNT(*) FROM $tableName'));
  }

  //根据id获取指定的数据
  Future<DataItem> getDataItem(String id) async {
    var dbClient = await db;
    List<Map> result = await dbClient.query(tableName,
        columns: [newsId, uniquekey, title, date , category , author_name , url , thumbnail_pic_s , thumbnail_pic_s02 , thumbnail_pic_s03 ,],
        where: '$newsId = ?',
        whereArgs: [id]);
    // var result = await dbClient.rawQuery('SELECT * FROM $tableName WHERE $columnId = $id');

    if (result.length > 0) {
      DataItem dataItem = DataItem.fromMap(result.first);
      return dataItem;
    }else{
      return null;
    }
  }

  //删除数据
  Future<int> deleteDataItem(String id) async {
    var dbClient = await db;
    return await dbClient.delete(tableName, where: '$newsId = ?', whereArgs: [id]);
//    return await dbClient.rawDelete('DELETE FROM $tableNote WHERE $columnId = $id');
  }

  //清空数据库
  Future<void> clearDataItem() async {
    var dbClient = await db;
    return await dbClient.rawQuery('DELETE FROM $tableName');
  }

  //修改一条数据
  // Future<int> updateDataItem(DataItem dataItem) async {
  //   var dbClient = await db;
  //   return await dbClient.update(tableName, dataItem.toMap(), where: "$newsId = ?", whereArgs: [dataItem.uniquekey]);
  // }

  //关闭数据库
  Future close() async {
    var dbClient = await db;
    return dbClient.close();
  }
}